import re
import os
import time

import requests


class web_init:
    """
    初始化数据
    """

    def __init__(self):
        self.the_log = []  # 错误日志
        self.url_re_text = None  # 网址返回内容
        self.url_title = None  # 网页title
        self.link_src = []  # src链接
        self.link_href = []  # href链接
        self.link_html = []  # html链接
        # 文件夹名称中不能包含的内容
        self.title_not = ["|", ",", ".", "，", "。", " ", "", "?", "、", "*", ">", "<", "@", "%", "$", "/", ":", "：", "-",
                          "—", "\\", "·", ";", "；", "#", "!", "！"]
        self.main_folder = None  # 主文件夹名称


class web_pa(web_init):
    """
    web中数据处理
    """

    # 进行网址请求
    def url_re(self, url):
        try:
            self.url_re_text = requests.get(url).text  # 进行get请求
        except BaseException as b:
            # 获取当前时间
            time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
            # 将错误写入日志
            self.the_log.append(str(b) + time_text + "网址请求错误,发起的网址为：" + url)  # 进行post请求
            self.url_re_text = requests.post(url).text

    # 进行网页链接提取
    def link_extract(self):
        title = re.findall("<title>.+?</title>", self.url_re_text)  # title提取
        src = re.findall('src=".+?"', self.url_re_text)  # src链接提取
        href = re.findall('href=".+?"', self.url_re_text)  # href链接提取
        html = re.findall('href=".+?.html"', self.url_re_text)  # html链接提取
        # 将获取到的内容进行添加
        for i in title:
            self.url_title = self.name_dis(i[7::][:-8])  # title
        # src链接
        for i in src:
            self.link_src.append(i[5::][:-1])
        # href链接
        for i in href:
            self.link_href.append(i[6::][:-1])
        # html链接
        for i in html:
            self.link_html.append(i[6::][:-1])

    # 名称处理
    def name_dis(self, text):
        # 临时列表
        temp_list = []
        temp_text = ""
        # 逐字进行判断title内容
        for i in list(text):
            if i in self.title_not:
                i = "_"
                temp_list.append(i)
            else:
                temp_list.append(i)
        # 将获取到的内容进行拼接
        for i in temp_list:
            temp_text = str(temp_text) + str(i)

        return temp_text


class folder_pa(web_pa):
    """
    文件夹类处理
    """

    # 进行相关文件夹创建
    def folder_mkdir(self):
        n = 0
        # 创建主文件夹
        for i in range(10):
            if n < 1:
                path_name = self.folder_creation(self.url_title)  # 进行文件夹路径合并
                self.folder_creation_perform(path_name)  # 进行主文件夹创建
                self.main_folder = path_name  # 主文件夹名称进行上报
            else:
                time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
                self.the_log.append(str(time_text) + "文件夹重复创建,重建次数：" + str(n))
            n += 1

    # 文件夹路径合并
    def folder_creation(self, name, head="./"):
        """
        文件夹路径合并
        :param name: 需要创建的文件夹名称
        :param head: 文件夹前置路径
        :return:
        """
        if name is not None or name != "None":
            try:
                path_name = os.path.join(head, name)
                return path_name
            except BaseException as b:
                time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
                self.the_log.append(str(time_text) + str(b) + "文件路径合并处理错误，处理名称为：" + str(name))
        else:
            time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))  # 获取时间
            path_name = os.path.join("./", str(time_text) + "请求文件夹")  # 文件夹路径合并
            self.the_log.append(time_text + "文件夹路径合并错误，请求名称为：" + str(name))  # 异常上报
            return path_name

    # 进行文件夹创建执行
    def folder_creation_perform(self, name):
        """
        进行文件夹的创建
        :param name: 创建的文件夹路径及名称
        :return:
        """
        if name is not None or name != "":
            try:
                os.mkdir(str(name))
            except BaseException as b:
                # 获取当前时间
                time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
                self.the_log.append(str(b) + time_text + "文件夹创建错误,创建的文件名称为：" + str(name))
        else:
            time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))  # 获取时间
            path_name = os.path.join("./", str(time_text) + "请求文件夹")  # 文件夹路径合并
            os.mkdir(path_name)  # 创建文件夹
            self.main_folder = path_name  # 文件夹名称上传
            self.the_log.append("主文件夹为空" + time_text + "文件夹创建错误,创建的文件名称为：" + str(name))  # 异常上报


class file_dispose_pa(folder_pa):
    """
    进行文件处理
    """

    # 进行文件保存
    def file_save(self, url, file_name, file_lays, file_path):
        """
        请求地址，文件名，文件后缀，文件保存地址

        :param url:         请求地址
        :param file_name:   文件名
        :param file_lays:   文件后缀
        :param file_path:   文件保存地址
        :return:
        """
        # 文件名 + 文件后缀
        file_lay = file_name + file_lays
        # 进行网络请求
        file_req = requests.get(url)
        # 进行文件保存
        try:
            f = open(os.path.join(file_path, file_lay), "wb")  # 打开文件流
            f.write(file_req.content)  # 进行文件的写入
            f.close()  # 关闭文件流
        except BaseException as b:
            time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
            # 进行错误上报
            self.the_log.append(str(time_text) + str(b) + "图片类文件写入错误")

    # 图片类处理
    def image_dis(self):
        image_list = [".png", ".jpg"]
        # 进行文件夹创建
        path = self.folder_creation("image", head=self.main_folder)  # 文件地址合并
        self.folder_creation_perform(path)  # 进行文件夹创建
        # 进行链接提取
        for i in self.link_src:
            if i[-4::] in image_list:  # 如果是图片类文件则进行保存
                try:
                    if i[:2] == "//":
                        print("成功保存文件", "https:" + i, i[-9:][:-5], i[-4::], path)
                        self.file_save("https:" + i, self.name_dis(i[-9:][:-5]), i[-4::], path)
                    if i[:4] == "http":
                        print("成功保存文件", i, self.name_dis(i[-9:][:-5]), i[-4::], path)
                        self.file_save(i, i[-9:][:-5], i[-4::], path)
                except BaseException as b:
                    time_text = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))
                    self.the_log.append(str(time_text) + str(b) + "图片类文件写入错误_链接错误")


class main_pa(file_dispose_pa):
    """
    整体执行操作
    """

    # 将获取到的内容进行输出
    def pri(self):
        print(self.url_title)
        for i in self.link_href:
            print(i)
        for i in self.link_src:
            print(i)
        for i in self.link_html:
            print(i)

    # 进行执行
    def main(self, url):
        print("——————————————开始执行————————————————")
        self.url_re(url)
        print("——————————————链接提取————————————————")
        self.link_extract()
        print("——————————————创建文件夹————————————————")
        self.folder_mkdir()
        print("——————————————文件保存————————————————")
        self.image_dis()
        print("——————————————开始输出————————————————")
        self.pri()
        print("——————————————错误日志————————————————")
        for i in self.the_log:
            print(i)


if __name__ == '__main__':
    # url_l = "https://www.360.com"
    # url_l = "https://pvp.qq.com/"
    # url_l = "https://www.hua.com/?sid=pzbp&utm_source=baidu&utm_medium=pz&utm_term=PC-biaoti"
    # url_l = "https://www.bilibili.com/"
    url_l = "https://www.baidu.com/"
    main_pa().main(url_l)
    # a = web_pa().folder_creation("中文")
    # print(a)
    # web_pa().folder_creation_perform(a)
